﻿unit Easemob.Utils;

interface

uses

  System.SysUtils, System.Classes, IPPeerClient, REST.Client, System.JSON,
  Data.Bind.Components, Data.Bind.ObjectScope, MVCFramework.RESTClient,
  System.Net.HttpClientComponent,System.Net.HttpClient,
  REST.Authenticator.Basic,IdHTTP,System.Zip,Winapi.Windows,Ecaan.DB;

type

  [MVCPath('/')]
  TEasemobApi = class(TObject)
  private
    Params: TStringList;
    FRESTClient:TRESTClient;
  public
    constructor Create(client_id,client_secret,org_name,app_name,Url:string);
    destructor Destroy; override;

    function getUsers(limit:Integer = 0):string;
    //群组转让
    function changeGroupOwner(group_id,UserName_:string):string;
    function createGroup(groupname,desc,maxusers,owner:string;members:string= ''):string;
    function modifyGroupInfo(groupname,description,maxusers:string):string;

    function deleteGroup(group_id:string):string;

    function getGroups(limit:Integer = 0):string;

    function createUser(user_name,pass_word,nickname:string):string;
    function getUser(user_name:string):string;
    function resetPassword(user_name,newpassword:string):string;
    function editNickname(user_name,nickname:string):string;
    function addGroupMember(group_id,user_name:string):string;

    function deleteUser(user_name:string):string;

    function getChatRecordForDate:string;

 protected
    procedure GetAToken;
    procedure DownloadFile(DURl,GzFile: string);
    function GetURLFileName(aURL: string): string;
    //function ReversePos(SubStr, S: String): Integer;
  end;
  var
   AToken,clientID,clientsecret,orgname,appname :string;
implementation
uses
  MVCFramework.Logger, MVCFramework.Serializer.Commons,
  Ecaan.command;//,System.Net;
{ TEasemob }

function TEasemobApi.addGroupMember(group_id, user_name: string): String;
 var
  JSONObject :TJSONObject;
  LResp: IRESTResponse;
  Response,LBody:string;
begin
  with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    // LBody := Format('{"newowner":[{"group_id":"%s","options":"%s"}]}',[group_id,UserName_]);
     LResp := doPOST(orgname+appname+'chatgroups/'+group_id+'/users/'+user_name,[],'');
  end;
  if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
 try
   JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);  //TJSONArray.Create
 finally
   JSONObject.Free;
 end;
 end;

function TEasemobApi.changeGroupOwner(group_id, UserName_: string): String;
 var
  JSONObject :TJSONObject;
  LResp: IRESTResponse;
  Response,LBody:string;
begin
  with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
     LBody := Format('{"newowner":[{"group_id":"%s","options":"%s"}]}',[group_id,UserName_]);

     LResp := doPUT(orgname+appname,[],LBody);
  end;
  if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
   JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
      Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);
   finally
     JSONObject.Free;
   end;
end;

constructor TEasemobApi.Create(client_id,client_secret,org_name,app_name,Url:string);
begin
  clientid:=client_id;
  clientsecret :=client_secret;
  orgname:=org_name;
  appname:=app_name;
  Params := TStringList.Create;
  FRESTClient := TRESTClient.Create(Url);
  FRESTClient.UseBasicAuthentication :=False;
  GetAToken;
end;

function TEasemobApi.createGroup(groupname, desc, maxusers, owner,
  members: string): String;
  var
  JSONObject:TJSONObject;
  LBody,Response,error,Token,Str: string;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
  with FRESTClient do
  begin
    UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
     LBody := format('{"groupname": "%s","desc": "%s","public":true,'+
     '"maxusers":"%s","approval":false,"owner":"%s"}',
     [groupname, desc, maxusers, owner]);
     LResp := FRESTClient.doPOST(orgname+appname+'/chatgroups', [], LBody);
  end;
      //获取网页返回的信息
  if not LResp.HasError then
   begin
     Response :=LResp.BodyAsString;// 输出结果
   end;
   try
   JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
     begin
       Str :=(JSONObject.GetValue('data') as TJSONObject).ToString;
     end else
      Str := GetDataToJson(0,TJSONArray.Create);

     Result :=Str;
   finally
     JSONObject.Free;
   end;
end;

function TEasemobApi.createUser(user_name,pass_word,nickname:string): String;
 var
  Response,LBody,nick_name:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
 nick_name :=nickname;
//   JSONObject := TJSONObject.Create(nil);
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LBody := format('{"username":"%s","password":"%s","nickname":"%s"}',
      [user_name,pass_word,nick_name]);

    LResp := doPOST(orgname+appname+'/users', [],LBody);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
  try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(1,TJSONArray.Create);
  finally
    JSONObject.Free;
  end;
end;

function TEasemobApi.deleteGroup(group_id: string): String;
 var
  Response:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LResp := doDELETE(orgname+appname+'/chatgroups/'+group_id, []);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);
   finally
     JSONObject.Free;
   end;
end;

function TEasemobApi.deleteUser(user_name: string): String;
 var
  Response,ID:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
  ID :=user_name;
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LResp := doDELETE(orgname+appname+'/users/'+ID,[]);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);
   finally
     JSONObject.Free;
   end;
end;

destructor TEasemobApi.Destroy;
begin
  FreeAndNil(Params);
  FreeAndNil(FRESTClient);
  inherited Destroy;
end;

procedure TEasemobApi.DownloadFile(Durl,GzFile: string);
  var
  PathDir,fielName: string;
  Cmd: AnsiString;
  list : TStringlist;
  NetHTTPClient1: TNetHTTPClient;
  ms:TMemoryStream;
begin
 PathDir := ExtractFilePath(GetModuleName(HInstance));
 try
  ms := TMemoryStream.Create;
  NetHTTPClient1 := TNetHTTPClient.Create(nil);
  NetHTTPClient1.Get(durl,ms);
  if durl.Length>0 then
   ms.SaveToFile(PathDir+GzFile);
 finally
   NetHTTPClient1.Free;
   ms.Free;
 end;
  killtask('gzip.exe');
  Sleep(2000);
  list := TStringlist.Create;
  list.Delimiter := '.';
  list.DelimitedText := GzFile;
  fielName := list.Strings[0];
  Cmd := PathDir+'gzip.exe -d '+PathDir+GzFile;
  // 命令行调用
  WinExec(PAnsiChar(Cmd), SW_HIDE);
  list.Free;
end;

function TEasemobApi.editNickname(user_name, nickname: string): String;
 var
  Response,LBody:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LBody :=format('{"nickname": "%s"}',[nickname]);
    LResp := doPut(orgname+appname+'/users/'+user_name, [],LBody);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);

   finally
     JSONObject.Free;
   end;

end;

function TEasemobApi.getChatRecordForDate: String;
 var
 fileName,DownFile :string;
 Response,DUrl:string;
 JSONObject,Jsobj : TJSONObject;
 LResp: IRESTResponse;
 dataArr:TJSONArray;
 v:string;
 i:Integer;
begin
  JSONObject := TJSONObject.Create;
  fileName :=FormatDateTime('YYYYMMDDHH',Date+Time-2/24 );
  with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
    UseBasicAuthentication:=False;
    with RequestHeaders do
    begin
      Values['Accept'] := 'application/json';
      Values['Authorization'] := AToken;
    end;
   LResp := doGET(orgname+appname+'/chatmessages/'+fileName,[]);
  end;
  if not LResp.HasError then
    begin
      Response :=LResp.BodyAsString;// 输出结果
    end;
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
     begin
      dataArr :=TJSONArray(JSONObject.GetValue('data'));
      for i := 0 to dataArr.Size-1 do
       begin
        v:=(dataArr.Items[i].ToString);
        Jsobj:=TJSONObject.ParseJSONValue(v)  as TJSONObject;
        DUrl := Jsobj.GetValue('url').Value;
      end;
       DownFile :=GetURLFileName(DUrl);
       DownloadFile(DUrl,DownFile);
       Result := DownloadFileToJson(1,Copy(DownFile,1,DownFile.Length-3));
     end
   else
      Result := DownloadFileToJson(0,'');
end;

function TEasemobApi.GetURLFileName(aURL: string): string;
var
  i: integer;
  s: string;
begin
  s := aURL;
  i := Pos('/', s);
  while i <> 0 do
   begin
    Delete(s, 1, i);
    i := Pos('/', s);
  end;
  s :=Copy(s,1,Pos('?',s)-1);
  Result := s;
end;

function TEasemobApi.getGroups(limit: Integer): String;
 var
  Response:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    with QueryStringParams do
    begin
      Values['limit'] := limit.ToString;
    end;
    LResp := doGET(orgname+appname+'/chatgroups', []);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);
   finally
    JSONObject.Free;
   end;

end;

function TEasemobApi.getUser(user_name: string): String;
 var
  Response,user,Str:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
  user := user_name;
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LResp := doGET(orgname+appname+'/users/'+user, []);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Str := GetDataToJson(1,TJSONArray.Create)//JSONObject
   else
      Str := GetDataToJson(0,TJSONArray.Create);
      Result := Str;
   finally
     JSONObject.Free;
   end;
end;

function TEasemobApi.getUsers(limit: Integer = 0): String;
 var
  Response:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    with QueryStringParams do
    begin
      Values['limit'] := limit.ToString;
    end;
    LResp := doGET(orgname+appname+'/users', []);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);

   finally
    JSONObject.Free;
   end;
end;

function TEasemobApi.modifyGroupInfo(groupname, description, maxusers: string): String;
  var
  JSONObject:TJSONObject;
  LBody,Response,error,Token: string;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
  with FRESTClient do
  begin
    UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
     LBody := format('{"groupname": "%s","description": "%s",'+
     '"maxusers":"%s"}',[groupname, description, maxusers]);
    LResp := FRESTClient.doPUT(orgname+appname+'/chatgroups', [], LBody);
  end;
      //获取网页返回的信息
  try
  if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
        JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
        Result := JSONObject.ToJSON;
      end
   else
       Result := GetDataToJson(0,TJSONArray.Create);
  finally
    JSONObject.Free;
  end;
end;

function TEasemobApi.resetPassword(user_name, newpassword: string): String;
 var
  Response,LBody,str:string;
  JSONObject,JO : TJSONObject;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
 with FRESTClient do
  begin
    // 这里必须TRESTClient首次执行命令前就赋值，后续的变更是无效的
     UseBasicAuthentication:=False;
   with RequestHeaders do
    begin
      Values['Authorization'] := AToken;
    end;
    LBody :=format('{"newpassword": "%s"}',[newpassword]);
    LResp := doPut(orgname+appname+'/users/'+user_name+'/password', [],LBody);
  end;
   if not LResp.HasError then
      begin
        Response :=LResp.BodyAsString;// 输出结果
      end;
   try
    JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    if JSONObject <> nil then
       Result := JSONObject.ToJSON
   else
      Result := GetDataToJson(0,TJSONArray.Create);
   finally
    JSONObject.Free;
   end;

end;

//function TEasemobApi.ReversePos(SubStr, S: String): Integer;
//var
//  i : Integer;
//begin
//  i := Pos(ReverseString(SubStr), ReverseString(S));
//  if i > 0 then i := Length(S) - i - Length(SubStr) + 2;
//  Result := i;
//end;

procedure TEasemobApi.GetAToken;
  var
  JSONObject:TJSONObject;
  LBody,Response,error,Token: string;
  LResp: IRESTResponse;
begin
   JSONObject := TJSONObject.Create;
   LBody := format('{"grant_type": "client_credentials","client_id": "%s","client_secret": "%s"}',[clientid,clientsecret]);
    LResp := FRESTClient.doPOST(orgname+appname+'/token', [], LBody);
    if not LResp.HasError then
    begin
      Response :=LResp.BodyAsString;      // 输出结果
      JSONObject := TJSONObject.ParseJSONValue(Response) as TJSONObject;
    end;
      //获取网页返回的信息
      if JSONObject <> nil then
      begin
        AToken := StringReplace('Bearer '+JSONObject.GetValue('access_token').ToString,'"','',[rfReplaceAll]);
      end else
      AToken :='Bearer ';
end;

end.
